package pl.wroc.pwr.mss.server.ui.tables;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JTable;
import javax.swing.event.ListSelectionEvent;

import pl.wroc.pwr.mss.logic.domain.Playlist;
import pl.wroc.pwr.mss.server.service.PlaylistService;
import pl.wroc.pwr.mss.server.ui.dialogs.JPlaylistEditDialog;
import pl.wroc.pwr.mss.server.ui.menu.JPlaylistPopupMenu;
import pl.wroc.pwr.mss.server.ui.tables.models.PlaylistTableModel;
import pl.wroc.pwr.mss.server.util.JTableUtils;

/**
 * Tabela przechowujaca nazwy playlist.
 * 
 * @author mjagus
 */
public class JPlaylistTable extends JTable
{
    /**
     * Identyfikator klasy.
     */
    private static final long serialVersionUID = 3441605834836978020L;

    /**
     * Tabela utworow dla playlisty wybranej w tej tabeli.
     */
    private JSongTable songTable;

    /**
     * Serwis dla encji Playlist.
     */
    private PlaylistService playlistService;

    /**
     * Okno dialogowe edycji playlisty.
     */
    private JPlaylistEditDialog playlistEditDialog;

    /**
     * Menu wyskakujace dla tej tabeli.
     */
    private JPlaylistPopupMenu playlistPopupMenu;

    /**
     * Iniciuje komponent.
     */
    public JPlaylistTable()
    {
        super();

        super.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        super.getSelectionModel().addListSelectionListener(this);
        super.addMouseListener(new PlaylistTableMouseAdapter());
    }

    @Override
    public void valueChanged(ListSelectionEvent e)
    {
        super.valueChanged(e);

        if(!e.getValueIsAdjusting())
        {
            Playlist playlist = getSelectedPlaylist();

            songTable.setPlaylist(playlist);
            JTableUtils.adjustColumns(songTable);
        }
    }

    /**
     * Zwraca playliste aktualnie zaznaczona w tabeli lub <code>null</code>
     * jesli zadna playlista nie jest aktualnie zaznaczona. W przypadku gdy
     * na tabeli jest wiele zaznaczonych pozycji, metoda zwraca te pierwsza.
     * 
     * @return Playlista zaznaczona na tabeli lub <code>null</code>
     */
    public Playlist getSelectedPlaylist()
    {
        int row = super.getSelectedRow();

        if(row != -1)
            return getPlaylists().get(row);
        else
            return null;
    }

    /**
     * Zwraca liste playlist zaznaczonych aktualnie na tabeli. W przypadku gdy
     * na tabeli zadna playlista nie jest zaznaczona, zwracana jest lista pusta.
     * 
     * @return Lista zaznaczonych na tabeli playlist
     */
    public List<Playlist> getSelectedPlaylists()
    {
        List<Playlist> playlists = new ArrayList<Playlist>();
        int[] rows = super.getSelectedRows();
        for(int rowIndex : rows)
            playlists.add(getPlaylists().get(rowIndex));

        return playlists;
    }

    /**
     * @return Tabela utworow powiazana z ta tabela
     */
    public JSongTable getSongTable()
    {
        return songTable;
    }

    /**
     * @param songTable Tabela utworow powiazana z ta tabela
     */
    public void setSongTable(JSongTable songTable)
    {
        this.songTable = songTable;
    }

    /**
     * @return Serwis dla encji Playlist
     */
    public PlaylistService getPlaylistService()
    {
        return playlistService;
    }

    /**
     * @param playlistService Serwis dla encji Playlist
     */
    public void setPlaylistService(PlaylistService playlistService)
    {
        this.playlistService = playlistService;
    }

    /**
     * @return Lista playlist wyswietlana w tej tabeli
     */
    public List<Playlist> getPlaylists()
    {
        return ((PlaylistTableModel)super.getModel()).getPlaylists();
    }

    /**
     * @param playlists Lista playlist wyswietlana w tej tabeli
     */
    public void setPlaylists(List<Playlist> playlists)
    {
        ((PlaylistTableModel)super.getModel()).setPlaylists(playlists);
    }

    /**
     * @return Okno dialogowe edycji playlisty
     */
    public JPlaylistEditDialog getPlaylistEditDialog()
    {
        return playlistEditDialog;
    }

    /**
     * @param playlistEditDialog Okno dialogowe edycji playlisty
     */
    public void setPlaylistEditDialog(JPlaylistEditDialog playlistEditDialog)
    {
        this.playlistEditDialog = playlistEditDialog;
    }

    /**
     * @return Menu wyskakujace dla tej tabeli
     */
    public JPlaylistPopupMenu getPlaylistPopupMenu()
    {
        return playlistPopupMenu;
    }

    /**
     * @param playlistPopupMenu Menu wyskakujace dla tej tabeli
     */
    public void setPlaylistPopupMenu(JPlaylistPopupMenu playlistPopupMenu)
    {
        this.playlistPopupMenu = playlistPopupMenu;
    }

    /**
     * Adapter myszy komputerowej nasluchujacy zdarzen na tabeli z playlistami.
     * 
     * @author mjagus
     */
    private class PlaylistTableMouseAdapter extends MouseAdapter
    {
        @Override
        public void mouseClicked(MouseEvent e)
        {
            if(e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2)
            {
                playlistEditDialog.initPlaylist(getSelectedPlaylist());
                playlistEditDialog.setVisible(true);
            }
            else if(e.getButton() == MouseEvent.BUTTON3)
            {
                playlistPopupMenu.show(e.getComponent(), e.getX(), e.getY());
            }
        }
    }
}
